package common

import (
	"fmt"
	"net"
	"os"
	"syscall"
)

func NewError(code int32, str string) *Error {
	return &Error{ErrCode: code, Str: str}
}

type Error struct {
	//错误码 0表示成功
	ErrCode int32
	//错误信息
	Str string
	//低层错误对象
	Err error
	//错误信息的参数
	Param []interface{}
}

func (e *Error) Unwrap() error { return e.Err }

func (e *Error) Error() string {
	if e == nil {
		return "<nil>"
	}
	if e.Err == nil {
		if len(e.Param) == 0 {
			return e.Str
		} else {
			return fmt.Sprintf(e.Str, e.Param...)
		}
	} else {
		if len(e.Param) == 0 {
			return fmt.Sprintf("%s suberror: %v", e.Str, e.Err)
		} else {
			return fmt.Sprintf("%s suberror: %v", fmt.Sprintf(e.Str, e.Param...), e.Err)

		}
	}

}

func (e *Error) String() string {
	return e.Error()
}

// 延长错误信息
func (e Error) NewErr(suberr error, param ...interface{}) error {
	e.Err = suberr
	e.Param = param
	return &e
}

// AppendMsg 用于通用错误 追加服务器更多信息,客户端不会展示的.
func (e Error) AppendMsg(fmat string, param ...interface{}) error {
	e.Str += "[服务器只读内容]:" + fmt.Sprintf(fmat, param...)
	return &e
}

// 从错误中读取最后的errno
func GetErrno(err error) int {
	if opErr, ok := err.(*net.OpError); ok {
		if sysCallErr, oks := opErr.Err.(*os.SyscallError); oks {
			if en, oko := sysCallErr.Err.(syscall.Errno); oko {
				return int(en)
			}
		}
	}
	return 0
}

// 获取对象的错误
func GetError(v any) error {
	if v, ok := v.(error); ok {
		return v
	} else {
		return &Error{ErrCode: -1, Str: "unknown error"}
	}
}
